package GameEngine;



/**
 * The StdPlayer class implements all methods that will be used 
 * to interact with the player.
 * 
 * This class uses the Player interface, which defines 
 * two methods (request and confirm). 
 * 
 * @see Player#request( Move opponentMove )
 * @see Player#confirm( Status boardStatus )
 */
@SuppressWarnings("unused")
public class StdPlayer implements Player {

    /**
     * Holds an instance of the Input reader class.
     * This avoids the creation of unnecessary instances.
     */
    private static Input feed = new Input();
    
    /**
     * Declares if a player is black or red.
     */
    private boolean black;

    /**
     * Holds the string representation of the color.
     */
    private String color;
    
    /**
     * Holds the last move of the opponent player.
     */
    private Move lastMove = null;

    /**
     * The default constructor initializes the input reader 
     * if needed and saves it to a static class property.
     * 
     * @see Input
     */
    public StdPlayer(boolean black)
    {
        //set color mode
        this.black = black;

        // assign color value
        this.color = this.black ? "black" : "red";

        // output player up message
        System.out.println("Player " + this.color + " comes up!");
    }

    /**
     * This method handles the interaction between the 
     * player and the playing field.
     * 
     * @param opponentMove The last move of the opponent player.
     * @return Returns An object that represents the current move.
     * @throws java.lang.Exception
     */
    public Move request(Move opponentMove, int turnsLeft) throws Exception
    {
        // init move array
        int mov[] = {-1, -1, -1, -1};

        // declare new Move object
        Move move = null;

        // declare data for current move
        boolean clockwise;

        // check if it is the first move
        if( opponentMove != null )
        {
            System.out.println("Got opponent move (" + opponentMove + "). ");
        }

        // returns null if board status is already != 0

        // read move from command line
            mov = feed.readIntArray(4, " ", "Input move (col, row, element, clockwise): ");

        // check give up
        if (mov == null) {
            return null;
        }

        // check input for row
        if ((mov[0] < 1) || (mov[0] > 6)) {
            throw new Exception("Invalid move (" + mov[0] + ", " + mov[1] + ")!");
        }

        // check input for column
        if ((mov[1] < 1) || (mov[1] > 6)) {
            throw new Exception("Invalid move (" + mov[0] + ", " + mov[1] + ")!");
        }

        // check input for element
        if ((mov[2] < 1) || (mov[2] > 4)) {
            throw new Exception("Invalid rotation (" + mov[2] + ")!");
        }

        // check input for clockwise
        if ((mov[3] != 0) && (mov[3] != 1)) {
            throw new Exception("Invalid clockwise val (" + mov[3] + ")!");
        }

        // get rotation direction
        clockwise = (mov[3] > 0) ? true : false;

        // init new Move
        move = new Move(this.black, mov[0], mov[1], mov[2], clockwise);

        // set move as last move
        this.lastMove = move;

        // output current move
        System.out.println("Your move is (" + move + ").");

        // create Move object
        return move;
    }

    /**
     * Checks if an error occurred or if an move was illegal.
     * 
     * @param boardStatus Information of the last move.
     * @throws java.lang.Exception
     */
    public void confirm(Status boardStatus) throws Exception
    {
        // check if last move is valid
        if (boardStatus.value() == Status.ILLEGAL_MOVE) {
            throw new Exception("Illegal move!");
        }

        // check if an error occurred
        if( boardStatus.value() == Status.ERROR )
        {
            throw new Exception("Error occurred!");
        }

        if (boardStatus.value() == Status.BLACK_WINS) {         // checks if black wins
            System.out.println("Black (@) wins!");

        }
        if (boardStatus.value() == Status.RED_WINS) {         // checks if red wins
            System.out.println("Red (#) wins!");
        }
        if (boardStatus.value() == Status.DRAW) {           // checks if a draw occurres
            System.out.println("Draw!");
        }
    }
    /**
     * This method executes local moves form network mode
     * @param move the move witch should be set
     * @param black the player witch should be check
     */
    public void setter(Move move, boolean black) {
        int ver, hor, quad;
        ver = move.column();
        hor = move.row();
        quad = move.element();
    }
}
